package com.acce.product.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.acce.system.config.ReturnCodes;
import com.acce.system.dao.ICompanyDao;
import com.acce.system.dao.IUserDao;
import com.acce.base.pojo.ArgsPojo;
import com.acce.base.pojo.ReturnPojo;
import com.acce.product.config.ErrorCodes;
import com.acce.product.dao.IBuyGoodsDao;
import com.acce.product.dao.IGoodsDao;
import com.acce.product.pojo.BuyGoods;
import com.acce.product.service.BuyGoodsService;
import com.acce.product.utils.Utils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

@Service("buyGoodsService")
public class BuyGoodsServiceImpl implements BuyGoodsService {

	private Logger logger = Logger.getLogger(BuyGoodsServiceImpl.class);
	
	@Resource
	IBuyGoodsDao buyGoodsDao;
	
	@Resource
	IGoodsDao goodsDao;
	
	@Resource
	IUserDao userDao;
	
	@Resource
	ICompanyDao companyDao;
	
	public ReturnPojo findBuyGoods(ArgsPojo args) {
		long t1 = System.currentTimeMillis();
		String business = args.getBusiness();
		JSONObject jb = (JSONObject)JSONObject.parse(business);
//		String atUserId = jb.getString("atUserId");
		String companyId = jb.getString("companyId");
		
		ReturnPojo result = new ReturnPojo();
		result.setServiceCode(args.getServiceCode());
		result.setReturnCode(ErrorCodes.oper_success.getCode());
		result.setReturnMsg(ErrorCodes.oper_success.getMessage());
		
		BuyGoods goods = new BuyGoods();
		goods.setCompanyId(companyId);
		goods.setValidity("1");
		goods.setCompanyDefaultState("1");
		List<BuyGoods> list = buyGoodsDao.getBuyGoodsByCondition(goods);
		long t3 = System.currentTimeMillis();
		logger.info("nsy-product::findBuyGoodsForEmployee ..." + list.size() + "-" +(t3 -t1));
		System.out.println("nsy-product::findBuyGoodsForEmployee ..." + list.size() + "-" +(t3 -t1));
		List<BuyGoods> first = new ArrayList<BuyGoods>();
		Map<String, List<BuyGoods>> second = new HashMap<String, List<BuyGoods>>();
		Map<String, List<BuyGoods>> third = new HashMap<String, List<BuyGoods>>();
		for(BuyGoods com:list) {
			if("1".equals(com.getLevelNum())) {
				first.add(com);
			}
			
			if("2".equals(com.getLevelNum())) {
				if(second.containsKey(com.getFather())) {
					List<BuyGoods> cs = second.get(com.getFather());
					cs.add(com);
					second.put(com.getFather(), cs);
				} else {
					List<BuyGoods> list2 = new ArrayList<BuyGoods>();
					list2.add(com);
					second.put(com.getFather(), list2);
				}
			}
			
			if("3".equals(com.getLevelNum())) {
				if(third.containsKey(com.getFather())) {
					List<BuyGoods> cs = third.get(com.getFather());
					cs.add(com);
					third.put(com.getFather(), cs);
				} else {
					List<BuyGoods> list3 = new ArrayList<BuyGoods>();
					list3.add(com);
					third.put(com.getFather(), list3);
				}
			}
		}
		
		long t4 = System.currentTimeMillis();
		logger.info("level list spends: " + "-" +(t4 -t3));
		System.out.println("level list spends: " + "-" +(t4 -t3));
		
		JSONArray jsons = new JSONArray();
		for(BuyGoods f1:first) {
			JSONObject j1o = (JSONObject)JSONObject.toJSON(f1);
			JSONArray j2s = new JSONArray();
			List<BuyGoods> s2s = second.get(f1.getSon());
			if(s2s != null) {
				JSONObject j2o = null;
				for(BuyGoods s2:s2s) {
					j2o = (JSONObject)JSONObject.toJSON(s2);
					List<BuyGoods> t3s = third.get(s2.getSon());
					JSONArray j3s = null;
					if(t3s != null) {
						j3s = (JSONArray)JSONArray.toJSON(t3s);
						j2o.put("children", j3s);
					}
					j2s.add(j2o);
				}
				j1o.put("children", j2s);
			}
			jsons.add(j1o);
		}
		
		long t2 = System.currentTimeMillis();
		logger.info("nsy-product::generate json spend: " + (t2-t4));
		logger.info("nsy-product::generate json total spend: " + (t2-t1));
		logger.info("nsy-product::findBuyGoodsForEmployee json result");
		result.setResult(jsons);
		return result;
	}

	@Transactional
	public ReturnPojo insertBuyGoods(ArgsPojo args) {
		String business = args.getBusiness();
		JSONObject jb = (JSONObject)JSONObject.parse(business);
//		String atUserId = jb.getString("atUserId");
		String companyId = jb.getString("companyId");
		String companyName = jb.getString("companyName");
		String companyType = jb.getString("companyType");
		String currTime = Utils.getCurrTimeMillions();
		
		ReturnPojo result = new ReturnPojo();
		result.setServiceCode(args.getServiceCode());
		
		List<BuyGoods> list = null;
		BuyGoods goods = new BuyGoods();
		list = buyGoodsDao.getBuyGoodsByCondition(goods);
		for(BuyGoods gd:list) {
			gd.setBuyGoodsId(Utils.makeProductId());
			gd.setCompanyId(companyId);
			gd.setCompanyName(companyName);
			gd.setCompanyType(companyType);
			gd.setValidity("1");
			gd.setCreateTime(currTime);
		}
		buyGoodsDao.insertBatchBuyGoods(list);
		
		result.setReturnCode(ErrorCodes.oper_success.getCode());
		result.setReturnMsg(ErrorCodes.oper_success.getMessage());
		return result;
	}

	@Transactional
	public ReturnPojo updateBuyGoods(ArgsPojo args) {
		String business = args.getBusiness();
		JSONObject jb = (JSONObject)JSONObject.parse(business);
		String atUserId = jb.getString("atUserId");
		JSONObject create = (JSONObject)jb.get("create");
		JSONObject update = (JSONObject)jb.get("update");
		String currTime = Utils.getCurrTimeMillions();
		
		ReturnPojo result = new ReturnPojo();
		result.setServiceCode(args.getServiceCode());
		result.setReturnCode(ErrorCodes.oper_success.getCode());
		result.setReturnMsg(ErrorCodes.oper_success.getMessage());
		
		if(create != null) {
			BuyGoods base = JSONObject.parseObject(create.toJSONString(), BuyGoods.class);
			base.setBuyGoodsId(Utils.makeProductId());
			base.setValidity("1");
			base.setSyncType("1");
			base.setSyncTime(currTime);
			base.setCreateTime(currTime);
			base.setProQuantity("0");
			base.setSelected("0");
			base.setEditUserId(atUserId);
			base.setEditTime(currTime);
			
			//check exists
			BuyGoods check = new BuyGoods();
			check.setCompanyId(base.getCompanyId());
			check.setGoodsKingdom(base.getGoodsKingdom());
			check.setFather(base.getFather());
			check.setSon(base.getSon());
			check.setLevelNum(base.getLevelNum());
			check.setValidity(base.getValidity());
			
			if(StringUtils.isEmpty(base.getCompanyId())
				|| StringUtils.isEmpty(base.getGoodsKingdom())
				|| StringUtils.isEmpty(base.getFather())
				|| StringUtils.isEmpty(base.getSon())
				|| StringUtils.isEmpty(base.getLevelNum())) {
				logger.info("nsy-product::create buygoods::missing args{companyId, goodsKingdom, father, son, levelNum}.");
				result.setReturnCode(ReturnCodes.PARAM_NULL.getCode());
				result.setReturnMsg(ReturnCodes.PARAM_NULL.getMessage());
				return result;
			}
			
			List<BuyGoods> cks = buyGoodsDao.getBuyGoodsByCondition(check);
			if(cks != null && !cks.isEmpty()) {
				logger.info("nsy-product::create buygoods::goods name exists.");
				logger.info("nsy-product::create buygoods::create failure.");
				//exist then return
				result.setReturnCode(ErrorCodes.add_goods_failure.getCode());
				result.setReturnMsg(ErrorCodes.add_goods_failure.getMessage());
				return result;
			}
			logger.info("nsy-product::create buygoods::check over.");
			
			//get max sequenceNum
			BuyGoods sequence = new BuyGoods();
			sequence.setCompanyId(base.getCompanyId());
			sequence.setGoodsKingdom(base.getGoodsKingdom());
			sequence.setFather(base.getFather());
			sequence.setValidity(base.getValidity());
			List<BuyGoods> ses = buyGoodsDao.getBuyGoodsByCondition(sequence);
			int seq = 1;
			if(ses != null && !ses.isEmpty()) {
				//exist then return
				seq = Integer.valueOf(ses.get(0).getSequenceNum()) + 10;
			}
			logger.info("nsy-product::create buygoods sequenceNum: " + seq);
			base.setSequenceNum(seq+"");
			
			logger.info("nsy-product::create buygoods.");
			buyGoodsDao.insertBuyGoods(base);
			logger.info("nsy-product::create success.");
			result.setResult(base);
			logger.info("nsy-product::result: " + JSONObject.toJSONString(base));
		}
		if(update != null) {
			BuyGoods base = JSONObject.parseObject(update.toJSONString(), BuyGoods.class);
			base.setValidity("1");
			base.setSyncType("1");
			base.setSyncTime(currTime);
			logger.info("nsy-product::update buygoods.");
			buyGoodsDao.updateBuyGoods(base);
			logger.info("nsy-product::update success.");
		}
		return result;
	}
	
}
